package cn.gxufe.reliable.message.api.feign;

import cn.gxufe.reliable.message.api.holder.MessageHolder;
import cn.gxufe.reliable.message.common.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static cn.gxufe.reliable.message.common.Message.SOURCE_SERVICE_NAME;

/**
 * @author yingjie.rong
 **/
public class FeignRequestInterceptor implements RequestInterceptor {

    private static String sql = "insert into reliable_message(`key`,`header`,`data`,`status`,`id`,`other`) values (?,?,?,?,?,?)";

    private String PREPARE_METHOD="PUT";
    private String PREPARE_URL = "/message/prepare";

    private ObjectMapper objectMapper =  new ObjectMapper();

    @Value("${spring.application.name}")
    private String applicationName;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void apply(RequestTemplate template) {
        String method = template.method();
        template.header(SOURCE_SERVICE_NAME,applicationName);
        String url = template.url();
        Message message;
        String other ;
        try {
            message = objectMapper.readValue(new String(template.body()), Message.class);
            Assert.notNull( message.getData(),"message data 不能为空!" );
            Assert.notNull( message.getKey(),"message key 不能为空!" );
            Assert.notNull( message.getHeader(),"message header 不能为空!" );
            other   = objectMapper.writeValueAsString(MessageHolder.getMap());
            MessageHolder.setMessage(message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if(  PREPARE_METHOD.equals(method) && PREPARE_URL.equals(url) ){
            Assert.isNull( message.getId(),"message id  PREPARE 必须为空!" );
            try {
                message.setStatus(Message.STATUS_PREPARE);
                template.body(objectMapper.writeValueAsString(message));
                prepare(message,other);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
//        else {
//            throw new IllegalStateException("url is = " + url+", method = " + method );
//        }
    }

    private void prepare(Message message,String other) {
        List<Object[]> list = new ArrayList<>(1);
        Object[] args = new Object[]{Message.SOURCE_SERVICE_KEY_PREFIX + message.getKey(),message.getHeader(),message.getData(),message.getStatus(),message.getId(),other};
        list.add(args);
        jdbcTemplate.batchUpdate(sql,list);
    }



}
